package com.gict.antifraudback.controller.front.article;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gict.antifraudback.entity.Article;
import com.gict.antifraudback.entity.ArticleComment;
import com.gict.antifraudback.entity.LikeRecord;
import com.gict.antifraudback.entity.User;
import com.gict.antifraudback.exception.BusinessException;
import com.gict.antifraudback.result.ResultView;
import com.gict.antifraudback.service.ArticleCommentService;
import com.gict.antifraudback.service.ArticleService;
import com.gict.antifraudback.service.LikeRecordService;
import com.gict.antifraudback.service.UserService;
import com.gict.antifraudback.utils.IPUtils;
import com.gict.antifraudback.utils.UserThreadLocal;
import com.gict.antifraudback.vo.ArticleCommentVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ThinkPad
 */
@RestController
@Slf4j
@RequestMapping("/mapi/articleComment")
public class FrontArticleCommentController {

    @Autowired
    private ArticleCommentService articleCommentService;
    @Autowired
    private LikeRecordService likeRecordService;
    @Autowired
    private ArticleService articleService;
    @Autowired
    private UserService userService;

    /**
     * 获取文章的评论列表
     * @param articleCommentVo
     * @return
     */
    @PostMapping("/getListByArticleId")
    public ResultView getListByArticleId(@RequestBody ArticleCommentVo articleCommentVo) {
        if (articleCommentVo.getArticleId() == null) {
            throw new BusinessException("文章id不能为空！");
        }
        LambdaQueryWrapper<ArticleComment> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(articleCommentVo.getArticleId() != null, ArticleComment::getArticleId, articleCommentVo.getArticleId());
        wrapper.isNull(ArticleComment::getParentCommentId);  // 只查询是一级评论的
        IPage<ArticleComment> page = articleCommentService.page(new Page<>(articleCommentVo.getCurrent(), articleCommentVo.getPageSize()), wrapper);

        List<ArticleComment> records = page.getRecords();
        if (!records.isEmpty()){
            User thisUser = userService.getById(articleCommentVo.getUserId());
            // 获取id
            List<Integer> ids = records.stream().map(ArticleComment::getId).collect(Collectors.toList());
            // 实现回显是否点赞
            if (thisUser != null){
                List<LikeRecord> likeRecords = likeRecordService.listByIdsAndType(ids, "comment", thisUser.getId());
                if (!likeRecords.isEmpty()){
                    Map<Integer, LikeRecord> map = likeRecords.stream().collect(Collectors.toMap(LikeRecord::getTargetId, a -> a, (a, b) -> a));
                    for (ArticleComment record : records) {
                        LikeRecord likeRecord = map.get(record.getId());
                        if (likeRecord != null){
                            record.setLike(Boolean.TRUE);
                        }
                    }
                }
            }
            // 需要查询出关联的用户
            Set<Integer> set = new HashSet<>();
            set.addAll(records.stream().map(ArticleComment::getUserId).collect(Collectors.toList()));
            set.addAll(records.stream().map(ArticleComment::getToId).collect(Collectors.toList()));

            Collection<ArticleComment> articleComments = articleCommentService.listChildrenByIds(ids);
            Map<Integer, List<ArticleComment>> parentCommentMap;
            if (articleComments.isEmpty()){
               parentCommentMap = new HashMap<>();
            }else {
                set.addAll(articleComments.stream().map(ArticleComment::getUserId).collect(Collectors.toList()));
                set.addAll(articleComments.stream().map(ArticleComment::getToId).collect(Collectors.toList()));

                parentCommentMap = articleComments.stream().collect(Collectors.groupingBy(ArticleComment::getParentCommentId));
            }
            // TODO
            Map<Integer, Map<String, Long>> countMap = likeRecordService.countByArticleCommentIdsAndType(ids);

            Collection<User> users = userService.listByIds(new ArrayList<>(set));
            if (CollectionUtils.isNotEmpty(users)) {
                Map<Integer, User> map = users.stream().collect(Collectors.toMap(User::getId, a -> a));
                // 评论的用户头像跟昵称
                for (ArticleComment record : records) {
                    List<ArticleComment> comments = parentCommentMap.get(record.getId());
                    if (CollectionUtils.isNotEmpty(comments)) {
                        for (ArticleComment comment : comments) {
                            setUser(map, comment);
                        }
                        record.setReply(comments);
                        record.setIsExpand(Boolean.FALSE);
                    } else {
                        record.setReply(new ArrayList<>());
                        record.setIsExpand(Boolean.TRUE);
                    }
                    record.setLikeNum(Math.toIntExact(countMap.get(record.getId()) == null ? 0 : countMap.get(record.getId()).get("count")));
                    // 设置评论者
                    setUser(map, record);
                }
            }
        }

        return ResultView.ok(page);
    }

    private static void setUser(Map<Integer, User> map, ArticleComment comment) {
        // 设置评论者
        User user = map.get(comment.getUserId());
        if (user != null){
            comment.setUserEmail(user.getEmail());
            comment.setUserName(user.getName());
            comment.setUserAvatar(user.getAvatar());
        }
        // 设置被评论者
        User to = map.get(comment.getToId());
        if (to != null){
            comment.setToName(to.getName());
            comment.setToAvatar(to.getAvatar());
        }
    }

    /**
     * 删除评论
     * @param map
     * @return
     */
    @PostMapping("/deleteById")
    public ResultView deleteById(@RequestBody Map<String, Object> map) {
        Object id = map.get("id");
        if (id == null){
            throw new BusinessException("id is null");
        }
        articleCommentService.removeById(id.toString());
        // todo 是否需要删除子评论
        return ResultView.okMsg("删除成功");
    }

    /**
     * 评论
     * @param articleComment
     * @return
     */
    @PostMapping("/comment")
    public ResultView comment(@RequestBody ArticleComment articleComment, HttpServletRequest request) {
        articleComment.setUserId(UserThreadLocal.get().getId());
        articleComment.setUserAgent(request.getHeader("user-agent"));
        articleComment.setIp(IPUtils.getIpAddr(request));
        articleComment.setCreateTime(new Date());
        articleCommentService.save(articleComment);

        User user = UserThreadLocal.get();
        articleComment.setUserAvatar(user.getAvatar());
        articleComment.setUserName(user.getName());

        User toUser = userService.getById(articleComment.getToId());
        if (toUser != null){
            articleComment.setToAvatar(toUser.getAvatar());
            articleComment.setToName(toUser.getName());
        }
        articleComment.setIsExpand(Boolean.TRUE);
        articleComment.setLikeNum(0);
        articleComment.setLike(Boolean.FALSE);

        return ResultView.ok(articleComment);
    }
}
